#include "thread.h"
#include "file.h"
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#include <QFileInfo>
#include <QStringList>
#include <QDir>
#include <QDebug>

#include "/usr/include/python2.7/Python.h"

#define MAX_SIZE 1024

//解压
Thread::Thread(QString path, QString name, QString runpath) : QThread()
{
    this->runPath = runpath;
    this->debfile_path = path;
    this->soft_name = name;
    bflag = false;
    intClassification = 1;
}

//打包
Thread::Thread(QString pack_command) : QThread()
{
    this->pack_command = pack_command;
    bflag_c = false;
    intClassification = 2;
}

//生成文件 python
Thread::Thread(int bFlag_type, QString str_Source, QString cache_dir, thread_type_of_Python thread_type) : QThread()
{
    this->bFlag_type = bFlag_type;
    this->str_Source = str_Source;
    this->cache_dir = cache_dir;
    this->thread_type = thread_type;
    intClassification = 3;
}

Thread::~Thread()
{

}

void Thread::run()
{
    //是python
    if( intClassification == 3 )
    {
        qDebug() << "python type：" << this->thread_type ;
        switch (this->thread_type) {
        case py_filelist:
        {
            qDebug() << "py_filelist";
            createCPKfilelist();
            break;
        }
        case py_control_xml:
        {
            qDebug() << "py_control_xml";
            break;
        }
        case py_script:
        {
            qDebug() << "py_script";
            break;
        }
        case py_set_script:
        {
            qDebug() << "py_set_script";
            break;
        }
        default:
        {
            qDebug() << "python type：" << this->thread_type ;
            break;
        }

        }
    }
    //    是解压
    else if(bflag == false && intClassification == 1)
    {
        extractdebdata(debfile_path,   soft_name,  runPath);
        bflag = true;
    }
    //    是打包
    else if(bflag_c == false && intClassification == 2)
    {
        package(pack_command);
        bflag_c = true;
    }
}

//解压软件包
void Thread::extractdebdata(QString debfile_path, QString  soft_name, QString runPath)
{
    qDebug("make  ---dirent successfully!\n");
    QString a,b,c;
    QFileInfo f(debfile_path.toLocal8Bit().data());
    File fshell;
    if(!f.exists())
    {
        //创建文件夹
        if(mkdir(debfile_path.toLocal8Bit().data(), 00700) < 0)
        {
            printf("mkdir error!\n");
            //exit(1);
        }
    }

    //区分rpm包和deb包
    QStringList strList;
    strList = soft_name.split(".");
    int n = strList.size();
    std::string s = strList.at(n-1).toLocal8Bit().data();
    if(!strcmp(strList.at(n-1).toLocal8Bit().data(), "deb"))
    {
        strList = soft_name.split(".deb");
        a = QString("cd %1 && ar -x %2 && cd %3").arg(debfile_path).arg(soft_name).arg(runPath);
        //system(a.toStdString().c_str());
        fshell.inputShell(a.toLocal8Bit().data());
        soft_name = strList.at(0).toLocal8Bit().data();
        cache_dir = debfile_path + soft_name +"_cache";
        QString debian = cache_dir + "/DEBIAN";
        QFileInfo fi(cache_dir.toLocal8Bit().data());
        if(fi.exists())
        {
            //QString deleteStr = QString("rm -rf %1").arg(cache_dir);
            // system(deleteStr.toLocal8Bit().data());
            // fshell.inputShell(deleteStr.toLocal8Bit().data());
            //qDebug("delete dirent successfully!\n");
            qDebug("it already exist!\n");
        }
        else
        {
            //创建文件夹
            if(mkdir(cache_dir.toLocal8Bit().data(), 00700) < 0)
            {
                printf("mkdir error!\n");
                exit(1);
            }
            QFileInfo fi2(debian.toLocal8Bit().data());
            if(!fi2.exists())
            {
                if(mkdir(debian.toLocal8Bit().data(), 00700) < 0)
                {
                    printf("mkdir error!\n");
                    exit(1);
                }
            }

        }

        //有些os上生成data.tar.xz 有些生成data.tar.gz
        QFileInfoList list = QDir(debfile_path).entryInfoList();
        QString data_name;
        for (int i = 0; i < list.size(); ++i) {
            QFileInfo fileInfo = list.at(i);
            QStringList strList = fileInfo.fileName().split(".");
            if(!strcmp(strList.at(0).toLocal8Bit().data(), "data") &&
                    !strcmp(strList.at(1).toLocal8Bit().data(), "tar"))
            {
                data_name = fileInfo.fileName();
            }
        }
        b = QString("cd %1 && tar -xf  %2 -C %3 && tar -xf control.tar.gz -C %4").arg(debfile_path).arg(data_name).arg(cache_dir).arg(debian);
        //system(b.toStdString().c_str());
        fshell.inputShell(b.toLocal8Bit().data());

        c = QString("cd %1 && rm %2 control.tar.gz debian-binary").arg(debfile_path).arg(data_name);
        fshell.inputShell(c.toLocal8Bit().data());
        emit signal_Msg_extract_end();
    }
    else  if(!strcmp(strList.at(n-1).toLocal8Bit().data(), "rpm"))
    {
        qDebug() << "jieya le rpm";
        strList = soft_name.split(".rpm");
        QString sname = soft_name;
        soft_name = strList.at(0).toLocal8Bit().data();
        cache_dir = debfile_path + soft_name +"_cache";
        QFileInfo fi(cache_dir.toLocal8Bit().data());
        if(fi.exists())
        {
            //QString deleteStr = QString("rm -rf %1").arg(cache_dir);
            // system(deleteStr.toLocal8Bit().data());
            // fshell.inputShell(deleteStr.toLocal8Bit().data());
            //qDebug("delete dirent successfully!\n");
            qDebug("it already exist!\n");
        }
        else
        {
            //创建文件夹
            if(mkdir(cache_dir.toLocal8Bit().data(), 00700) < 0)
            {
                printf("mkdir error!\n");
                exit(1);
            }
        }
        a = QString("cd %1 && cp %2 %3").arg(debfile_path).arg(sname).arg(cache_dir);
        fshell.inputShell(a.toLocal8Bit().data());
        b = QString("cd %1 && rpm2cpio %2 2>$HOME/error.info| cpio -div && cd %3").arg(cache_dir).arg(sname).arg(runPath);
        fshell.inputShell(b.toLocal8Bit().data());
        c = QString("cd %1 && rm %2 && cd %3").arg(cache_dir).arg(sname).arg(runPath);
        fshell.inputShell(c.toLocal8Bit().data());

        ErrorInfo* error_info = new ErrorInfo();

        //        error.info文件正常打开，并且无错误信息
        if( error_info->isEnable && ! error_info->isError)
        {
            emit signal_Msg_extract_end();
        }
        //        error.info文件能打开，有错误信息
        else if( error_info->isEnable )
        {
            QString errorInfoDes = "错误可能：\n1.未安装rpm包管理工具\n2.软件包已损坏\n\n详细错误信息：\n";
            errorInfoDes.append(error_info->errorInfoDes);
            emit signal_Msg_error(errorInfoDes);
        }
        //        error.info文件不能打开
        else
        {
            emit signal_Msg_error("error.info文件无法打开");
        }

    }
}

void Thread::package(QString pack_command)
{
    qDebug() << pack_command;
    File fshell;
    fshell.inputShell( (pack_command + " 2>$HOME/error.info").toLocal8Bit().data());

    ErrorInfo* error_info = new ErrorInfo();

    if( error_info->isEnable && ! error_info->isError)
    {
        emit signal_Msg_pack_end(NULL);
    }
    else if( error_info->isEnable )
    {
        QString errorInfoDes = "错误可能：\n1.未安装CPKG\n2.该路径权限较高\n\n详细错误信息：\n";
        errorInfoDes.append(error_info->errorInfoDes);
        emit signal_Msg_error(errorInfoDes);
    }
    else
    {
        emit signal_Msg_error("error.info文件无法打开");
    }

}

void Thread::createCPKfilelist()
{
    qDebug() << "createCPKfilelist";

    //预先生成CPK文件夹
    QString cpk_path;
    if(bFlag_type == 1) //打包
        cpk_path = str_Source +"/CPK";
    else if(bFlag_type == 2) //转包
        cpk_path = cache_dir +"/CPK";
    QFileInfo fi(cpk_path.toLocal8Bit().data());
    if(fi.exists())
    {
        qDebug("存在CPK文件夹!（生成filelist）\n");
        //return -1;
    }
    else
    {
        //创建文件夹
        if(mkdir(cpk_path.toLocal8Bit().data(), 00700) < 0)
        {
            //            printf("mkdir -cpkfilelistgeneration error!\n");
            //              exit(1);
            emit signal_Msg_error("生成filelist文件过程中发生错误\n\n详细错误信息：\nmkdir -cpkfilelistgeneration error!\n");
            //              return -1;
        }
    }

    PyObject* pModule;
    PyObject* pFunction;
    PyObject* pArgs;

    pModule = PyImport_ImportModule("filelist");
    if(!pModule){
        printf("import python  filelist failed!\n");
        emit signal_Msg_error("生成filelist文件过程中发生错误\n\n详细错误信息：\nimport python  filelist failed!\n");
        //                                  return -1;
    }
    else
    {
        printf("import python  filelist succeed!\n");
    }
    pFunction = PyObject_GetAttrString(pModule, "gen_filelist");
    if(!pFunction){
        printf("get python function failed!\n");
        //      return -1;
        emit signal_Msg_error("生成filelist文件过程中发生错误\n\n详细错误信息：\nget python function failed!\n");
        //                                  return -1;
    }
    pArgs = PyTuple_New(1);
    if(bFlag_type == 1) //打包
        PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", str_Source.toLocal8Bit().data()));
    else if(bFlag_type == 2) //转包
        PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", cache_dir.toLocal8Bit().data()));
    PyObject_CallObject(pFunction, pArgs);

    Py_DECREF(pModule);
    Py_DECREF(pFunction);
    Py_DECREF(pArgs);
    //      return 0;
    //      emit signal_Msg_py_filelist_end();
    emit signal_Msg_py_end(py_filelist);

}
